﻿//进制转换
//本文件由：周博儒(2021300004043) 贺镇涛（2021300004071）负责
#include<iostream>
#include<string>
#include<vector>
#include<cmath>
#include <algorithm>
#include"Trans.h"
using namespace std;
#define TOLOWER(p) {transform(p.begin(),p.end(),p.begin(),::tolower);}
//贺镇涛
void numer2()
{
	bool IsRe = 1;
	while (IsRe == 1)
	{
		cout << "请选择转换项目：\n0.退出\n1.二进制转十进制\n2.十进制转二进制\n3.二进制转八进制\n4.八进制转换二进制\n5.n进制转m进制\n";
		cout << "选择：";
		string temp;
		cin >> temp;
		short t;
		if (temp.size() == 1 && '0' <= int(temp[0]) && int(temp[0]) <= '5') { t = stoi(temp); }
		else
		{
			cout << "模式不合法！\n";
			t = 0;
		}
		if (t == 0) goto End;
		int n = 2, m = 2;
		if (t == 5)
		{
			cout << "请输入：原进制 目标进制：";
			cin >> n >> m;
		}
		string type;
		cout << "请输入数字:";
		cin >> type;
		string out;
		switch (t)
		{
		case(0):
		{
			out = "";
			IsRe = 0;
			break;
		}
		case(1):
		{
			out = num_2_to_10(type);
			break;
		}
		case(2):
		{
			out = num_10_to_2(type);
			break;
		}
		case(3):
		{
			out = num_2_to_8(type);
			break;
		}
		case(4):
		{
			out = num_8_to_2(type);
			break;
		}
		case(5):
		{
			out = num_n_to_m(type, n, m);
			break;
		}
		default:
		{
			out = "";
			IsRe = 0;
			break;
		}
		}
		RemoveZero(&out);//去除末尾的零
		cout << "结果为" << out << endl;
		cout << "<MATHTOYS:\\TRANS>\n";
	}
End:;
}

string num_2_to_10(string in)
{
	int quan = int(in.length()) - 1;			//位权
	int out = 0;
	for (int i = 0; i < in.length(); i++)
	{
		int temp = int(in[i]) - 48;
		out += int(temp * pow(2, quan));	//pow乘方依赖于<math.h>,且返回double
		quan--;
	}
	return to_string(out);
}

string num_10_to_2(string in)
{
	string out = "";
	long input = atoi(in.c_str());
	int remainder = 0;				//余数
	int R[64] = {};					//储存余数
	long quo = 0;					//商
	int n = 0;
	do
	{
		quo = input / 2;
		remainder = input % 2;
		R[n] = remainder;
		//cout << R[n] << endl;
		input = quo;
		n++;
	} while (quo != 0);							//n+1为余数的个数
	for (int i = 0; i <= 63; i++)
	{
		if (n <= 0) { break; }
		out += (R[n] + '0');
		n--;
	}
	reverse(out.begin(), out.end());				//反转out
	out += '.';									//为了满足main函数的要求：所有返回值包括小数点
	return out;
}

//周博儒
string num_2_to_8(string str)
{
	string out = "";
	int num = str.size() / 3;                   //将二进制数三位取数
	int len = str.size() % 3;                   //
	if (len != 0)
	{
		num += 1;
		for (int i = 0; i < 3 - len; i++)
		{
			str = "0" + str;
		}
	}
	for (int i = 0; i < str.size() - 1; i += 3)
	{
		out += to_string((str[i] - '0') * 4 + (str[i + 1] - '0') * 2 + (str[i + 2] - '0') * 1);
	}

	return out;
}

string num_n_to_m(string number, int n, int m)
{
	int ten = 0;
	int length = number.size();           //取数字的字节
	for (int i = 0; i < length; i++)               //将输入数字每一位提取出
	{
		if (number[i] >= '0' && number[i] <= '9')
			ten += (number[i] - '0') * pow(n, length - i - 1);          //每一位乘位权
		else
			ten += (number[i] - 'A' + 10) * pow(n, length - i - 1);     //将n进制的数转化为10进制的数
	}
	vector<int>n_con;                          //存放n_con数组                    
	int k;
	char q;
	string ncon;
	while (ten != 0)
	{
		n_con.push_back(ten % m);               //取原来数的m进制的余数
		ten = ten / m;                          //取原来数的商
	}
	for (int i = 0, j = n_con.size() - 1; i < j; i++, j--)
	{
		k = n_con[i];
		n_con[i] = n_con[j];
		n_con[j] = k;
	}
	for (int j = 0; j <= n_con.size() - 1; j++)
	{
		if (n_con[j] >= 10) q = n_con[j] - 10 + 'A';
		else q = n_con[j] - 0 + '0';
		ncon += q;                                                                 //得到m进制的数
	}
	return ncon;
}
//8_to_2
string num_8_to_2(string str)
{
	string out = "";
	int num = 0;
	vector<int>n_con;
	TOLOWER(str);
	sscanf(str.c_str(), "%o", &num);
	int con = 0;
	while (num / 2 != 0)
	{
		con = num % 2;
		n_con.push_back(con);
		num /= 2;
	}
	con = num % 2;
	n_con.push_back(con);
	reverse(n_con.begin(), n_con.end());
	for (int i = 0; i < n_con.size(); i++)
	{
		out += to_string(n_con[i]);
	}

	return out;
}
